package com.tnsw.coreutils;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.os.Build;
import android.os.Looper;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;

import com.tnsw.coreutils.queuemanager.QDelegateManager;
import com.tnsw.coreutils.queuemanager.QM;
import com.tnsw.coreutils.queuemanager.QueueInfo;
import com.tnsw.coreutils.queuemanager.iQM;
import com.tnsw.coreutils.queuemanager.queueobjects.QiNetworkLog;

public class AsyncManager implements iQM {

	private static boolean sIsRunning = false;
	private static AsyncManager sInstance;
	protected String logName = "ASYNCMANAGER";
	private QDelegateManager qm;
	
	public AsyncManager() {
		this(StaticConfig.ASYNC_THREAD_COUNT);
		
	}

	public AsyncManager(int threadCount) {
		this.qm = new QDelegateManager("ASYNCMANAGER", threadCount, this);
		this.qm.start();

		sInstance = this;
		sIsRunning = true;
	}
	
	public static AsyncManager getInstance() {
		if (sIsRunning == false) {
			sInstance = new AsyncManager();
		}
		
		return(sInstance);
	}
	
	public void addNewQueue(QueueInfo qi) {
		this.qm.addNewQueue(qi);
		
	}
	
	public void addNewQueue(Object obj) {
		QueueInfo qi = new QueueInfo(obj);
		this.qm.addNewQueue(qi);
	}
	
	public void addNewQueue(Object obj, int forceQueueId) {
		QueueInfo qi = new QueueInfo(obj, forceQueueId);
		this.qm.addNewQueue(qi);
	}

	@Override
	public void onNewQueueReceived(QM sender, QueueInfo qi) {
		if (qi.getObject() instanceof QiNetworkLog) {
			QiNetworkLog q = (QiNetworkLog) qi.getObject();
			ArrayList<NameValuePair> data = q.getData();
			if (q.getUrl().equals("")) {
				doHttpPost(StaticConfig.LOG_URL, data);	
			} else {
				doHttpPost(q.getUrl(), data);
			}
			
		}
		
	}
	
	public static HttpResponse doHttpPost(String url, ArrayList<NameValuePair> data) {
		//String ret = "";
		HttpResponse response = null;
		HttpClient httpClient = new DefaultHttpClient();
		HttpPost httpPost = new HttpPost(url);
		
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(data));
			response = httpClient.execute(httpPost);
			
			//data.add(new BasicNameValuePair("id", "12345"));
			if (response.getStatusLine().getStatusCode() != 200) {
				Log.e("AsyncManager.doHttpPost", "error, statuscode=" + response.getStatusLine().getStatusCode());
			}
			
			//ret = EntityUtils.toString(response.getEntity());
			 
		} catch (Exception e) {
			Log.e("Exception:AysncManager.doHttpPost", "url=" + url, e);
		}
		
		return(response);
	}
	
	public void appendNetworkLog(String url, ArrayList<NameValuePair> data) {
		QiNetworkLog q = new QiNetworkLog(data);
		q.setUrl(url);
		
		QueueInfo qi = new QueueInfo(q, 1);
		this.addNewQueue(qi);
	}
	
	public void appendBase64(String base64, String filename) {
		ArrayList<NameValuePair> data = new ArrayList<NameValuePair>();
		data.add(new BasicNameValuePair("filename", filename));
		data.add(new BasicNameValuePair("base64", base64));
		QiNetworkLog q = new QiNetworkLog(data);
		
		QueueInfo qi = new QueueInfo(q, 1);
		this.addNewQueue(qi);		
	}
	
	public static boolean isUiThread() {
		if (Looper.getMainLooper().equals(Looper.myLooper())) {
			return(true);
		} else {
			return(false);
		}
	}
	
	public void appendNetworkLog(String log) {
		ArrayList<NameValuePair> data = new ArrayList<NameValuePair>();
		data.add(new BasicNameValuePair("key", log));
		QiNetworkLog q = new QiNetworkLog(data);
		
		QueueInfo qi = new QueueInfo(q, 1);
		this.addNewQueue(qi);
	}
	
	public void dumpDeviceInfo(Context context) {
		AsyncManager asm = this;
		asm.appendNetworkLog("started dumping device info");
		
		StringBuffer sb = new StringBuffer();
		
		sb.append("CODENAME=" + android.os.Build.VERSION.CODENAME);
		sb.append("\r\nINCREMENTAL=" + android.os.Build.VERSION.INCREMENTAL);
		sb.append("\r\nRELEASE=" + android.os.Build.VERSION.RELEASE);
		sb.append("\r\nSDK=" + android.os.Build.VERSION.SDK);
		sb.append("\r\nSDK_INT=" + android.os.Build.VERSION.SDK_INT);
		sb.append("\r\nPRODUCT=" + Build.PRODUCT);
		
		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		sb.append("\r\nscreen_width=" + wm.getDefaultDisplay().getWidth());
		sb.append("\r\nscreen_height=" + wm.getDefaultDisplay().getHeight());
		sb.append("\r\nBuild.MODEL=" + Build.MODEL);
		sb.append("\r\nBuild.HARDWARE=" + Build.HARDWARE);
		
		sb.append("\r\n");
		asm.appendNetworkLog(sb.toString());
		asm.appendNetworkLog("ended dumping device info");
		
	}
	
	public static boolean isServiceRunning(Context context, String serviceName) {
		boolean b = false;
		
		ActivityManager manager = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);
		List<RunningServiceInfo> l = manager.getRunningServices(Integer.MAX_VALUE);
		for (RunningServiceInfo info : l) {
			if(info.service.getClassName().equals(serviceName)) {
				
				return(true);
			}
		}
		
		return(b);
	}
	
	public static boolean isEmulator() {
		boolean b = false;
		
		if (Build.PRODUCT.contains("sdk") == true) {
			b = true;
		}
		
		return(b);
	}
}
